package com.dashuai.utils.shardingarithmetic;

import com.dashuai.utils.date.DateUtil;
import com.google.common.collect.Range;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;

import java.util.ArrayList;
import java.util.Collection;


public class RangeTableShardingAlgorithm implements RangeShardingAlgorithm<Long> {


    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<Long> rangeShardingValue) {

        final ArrayList<String> result = new ArrayList<>();
        final Range<Long> range = rangeShardingValue.getValueRange();
        long startMillisecond = range.lowerEndpoint();
        long endMillisecond = range.upperEndpoint();

        // 起始年和结束年
        int startYear = Integer.parseInt(DateUtil.getYearByMillisecond(startMillisecond));
        int endYear = Integer.parseInt(DateUtil.getYearByMillisecond(endMillisecond));
        // 起始月和结束月
        int startMonth = Integer.parseInt(DateUtil.getMonthByMillisecond(startMillisecond));
        int endMonth = Integer.parseInt(DateUtil.getMonthByMillisecond(endMillisecond));

        int startYearJoinMonth = Integer.parseInt(DateUtil.getYearJoinMonthByMillisecond(startMillisecond));
        int endYearJoinMonth = Integer.parseInt(DateUtil.getYearJoinMonthByMillisecond(endMillisecond));
        return startYear == endYear ? theSameYear(startMonth, endMonth, availableTargetNames, result)
                : differentYear(startYear, endYear, startMonth, endMonth, startYearJoinMonth, endYearJoinMonth, availableTargetNames, result);
    }


    // 同年，但可能不同月
    private Collection<String> theSameYear(int startMonth, int endMonth, Collection<String> availableTargetNames, ArrayList<String> result) {

        return startMonth == endMonth ? theSameMonth(startMonth, availableTargetNames, result) : differentMonth(startMonth, endMonth, availableTargetNames, result);
    }

    // 同年同月
    private Collection<String> theSameMonth(int startMonth, Collection<String> availableTargetNames, ArrayList<String> result) {

        String startMonthStr = String.valueOf(startMonth);
        if (startMonthStr.length() == 1) startMonthStr = "0" + startMonthStr;
        for (String availableTargetName : availableTargetNames) {
            if (availableTargetName.endsWith(startMonthStr)) result.add(availableTargetName);
        }
        return result;
    }

    // 同年不同月
    private Collection<String> differentMonth(int startMonth, int endMonth, Collection<String> availableTargetNames, ArrayList<String> result) {

        for (String availableTargetName : availableTargetNames) {
            for (int i = startMonth; i <= endMonth; i++) {
                String monthStr = String.valueOf(i);
                if (monthStr.length() == 1) monthStr = "0" + monthStr;
                if (availableTargetName.endsWith(monthStr)) result.add(availableTargetName);
            }
        }
        return result;
    }


    // 不同年，跨年，最少两个月，需要考虑跨两年以上的情况
    private Collection<String> differentYear(int startYear, int endYear, int startMonth, int endMonth, int startYearJoinMonth, int endYearJoinMonth, Collection<String> availableTargetNames, ArrayList<String> result) {

        return endYear - startYear == 1 ? twoYears(startYear, endYear, startMonth, endMonth, startYearJoinMonth, endYearJoinMonth, availableTargetNames, result) : moreThanTwoYears(startYear, endYear, startMonth, endMonth, availableTargetNames, result);
    }


    // 两年
    private Collection<String> twoYears(int startYear, int endYear, int startMonth, int endMonth, int startYearJoinMonth, int endYearJoinMonth, Collection<String> availableTargetNames, ArrayList<String> result) {

        int endCondition;
        endCondition = Integer.parseInt(startYear + "12");
        for (int i = startYearJoinMonth; i <= endCondition; i++) {
            for (String availableTargetName : availableTargetNames) {
                // 如果多库此算法sharding会匹配两次，需要年份加月份来判断，只使用月份的话有问题
                if (availableTargetName.endsWith(String.valueOf(i))) result.add(availableTargetName);
            }
        }

        endCondition = Integer.parseInt(endYear + "01");
        for (int i = endYearJoinMonth; i >= endCondition; i--) {
            for (String availableTargetName : availableTargetNames) {
                if (availableTargetName.endsWith(String.valueOf(i))) result.add(availableTargetName);
            }
        }
        return result;
    }


    // 两年以上，如果数据量大的话不建议跨太多库
    private Collection<String> moreThanTwoYears(int startYear, int endYear, int startMonth, int endMonth, Collection<String> availableTargetNames, ArrayList<String> result) {
        return null;
    }

}
